from InputDefinition import InputDefinition
from OutputDefinition import OutputDefinition
from MappingDefinition import MappingDefinition
import threading
import time
import logging
import sys


class Listener():
	def __init__(self):
		self.input = None
		self.mapping = None
		self.output = None
		self.settings = None

		self.is_running = True
		self.is_done = False
		self.lock = threading.Lock()
		self.runner_thread = threading.Thread(target=self._loop)
		self.runner_thread.start()

		self.gui = None

	def set_gui(self, gui):
		self.gui = gui

	def _loop(self):
		while self.is_running is True:
			try:
				self._do_main()
			except Exception as e:
				logging.exception(e)
			finally:
				time.sleep(0.3)

		self.is_done = True

	def on_closing(self):
		self.is_running = False
		while self.is_done is False:
			time.sleep(0.1)
		sys.exit()

	def _do_main(self):
		if self.input is None or self.mapping is None or self.output is None or self.settings is None:
			return

		if self.settings['run'] is False:
			return

		if self.input.needs_detect():
			return

		values = self.input.get_values()
		mapped_values = self.mapping.map(values)
		new_status = self.output.execute(mapped_values)
		if new_status != '':
			self.gui.set_status(new_status)

	def set_definition(self, definition):
		if type(definition) is InputDefinition:
				self.input = definition
		elif type(definition) is MappingDefinition:
				self.mapping = definition
		elif type(definition) is OutputDefinition:
				self.output = definition

	def change_settings(self, settings):
		self.settings = settings
